#pragma once
#include <common.hpp>

namespace zzz{
template<typename T>
class Average
{
public:
  Average():ave_(0), count_(0){}

  const T Sum() const {return ave_*count_;}
  const zuint Count() const {return count_;}
  const T Mean() const {return ave_;}

  void AddData(const T &p)
  {
    ave_ = ave_*(double(count_)/(count_+1)) + p / double(count_+1);
    count_++;
  }

  template<typename T1>
  void AddData(const T1& _begin, const T1& _end)
  {
    for (T1 i=_begin; i!=_end; i++)
      AddData(*i);
  }

  void operator+=(const T &x)
  {
    AddData(x);
  }

  void operator+=(const vector<T> &x)
  {
    AddData(x.begin(), x.end());
  }

  void operator+=(const Average<T> &x)
  {
    ave_ = ave_*(double(count_)/(count_+x.count_)) + x.ave_*(double(x.count_)/(count_+x.count_));
    count_ += x.Count();
  }

private:
  T ave_;
  zuint count_;
};

}  // namespace zzz